/**
 * @Name: common-api
 * @Author: tyq
 * @version: 1.0.3
 * @Deprecated: 通用工具包-api
 * ----------------------------------------------------------------------------------------------------------------------------------
 * getUuid            生成UUID
 * deepClone          对象深度克隆
 * deepMerge          对象深度合并
 * random             返回一个范围之间的随机数
 * randomArray        打乱数组
 * toNumber           格式转换：数字格式(String => Number)
 * dateFormat         格式转换：时间格式
 * moneyFormat        格式转换：金额“,”分段格式化
 * arrayToTree        格式转换：数组转树
 * treeJson
 * pageJson
 * distinctJson
 * childJson
 * pivotJson
 * unpivotJson
 */

import {
	isNumber,
	isEmpty,
	isEmptys,
	isArray,
	isNull,
	isIos,
	isString
} from './validate'
import {
	ktluser
} from '@/utils';

const system = uni.getSystemInfoSync()

/****** getUuid 生成UUID ************************************************************************************************************/
/**
 * 获取uuid
 * @returns {string} uuid
 */
export function getUuid() {
	return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
		const r = Math.random() * 16 | 0;
		const v = c === 'x' ? r : (r & 0x3 | 0x8);
		return v.toString(16);
	})
}

export function getVersion() {
	return "8.1.38";
}


/****** deepClone 对象深度克隆 *******************************************************************************************************/
/**
 * 深度克隆
 * @param obj 被克隆的对象
 * @return {*}
 */
export function deepClone(obj) {
	// 对常见的“非”值、原始类型数据，直接返回原来值
	if (isEmpty(obj) || !['object', 'function'].includes(typeof obj)) return obj;

	// 构建克隆体
	var o = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {};
	for (let i in obj) {
		if (obj.hasOwnProperty(i)) {
			o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
		}
	}
	return o;
}


/****** deepMerge 对象深度合并 *******************************************************************************************************/
/**
 * 对象深度合并
 * @param {*} target 
 * @param {*} source 
 * @returns 
 */
export function deepMerge(target = {}, source = {}) {
	if (isEmpty(target) || typeof target !== 'object' || typeof source !== 'object') return false;

	for (var prop in source) {
		if (!source.hasOwnProperty(prop)) continue;
		if (prop in target) {
			if (typeof target[prop] !== 'object') {
				target[prop] = source[prop];
			} else {
				if (typeof source[prop] !== 'object') {
					target[prop] = source[prop];
				} else {
					if (target[prop].concat && source[prop].concat) {
						target[prop] = target[prop].concat(source[prop]);
					} else {
						target[prop] = deepMerge(target[prop], source[prop]);
					}
				}
			}
		} else {
			target[prop] = source[prop];
		}
	}
	return target;
}


/****** random 返回一个范围之间的随机数 ***********************************************************************************************/
/**
 * 返回一个范围之间的随机数
 * @param {Number} min
 * @param {Number} max
 */
export function random(min, max) {
	if (min >= 0 && max > 0 && max >= min) {
		let gab = max - min + 1;
		return Math.floor(Math.random() * gab + min);
	} else {
		return 0;
	}
}


/****** randomArray 打乱数组 ********************************************************************************************************/
/**
 * 打乱数组
 */
export function randomArray(array = []) {
	try {
		// 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0
		return array.sort(() => Math.random() - 0.5);
	} catch (e) {
		console.error(e);
	}
}

/****** toNumber 格式转换：数字格式(String => Number) *********************************************************************************/
/**
 * 数字格式转化：String => Number
 * @param {String} str 
 * @returns {Number} Number格式，如果参数不可转，返回0
 */
export const toNumber = str => isNumber(str) ? str / 1 : 0


/****** dateFormat 格式转换：时间格式 *************************************************************************************************/
/**
 * 日期格式转换
 * @param { String | Date | Number } val 需要转换的值
 * @param { String } format 转换的格式，默认年月日(YYYY-MM-DD)
 * @returns 格式化日期字符串
 */
export function dateFormat(val = null, format = "YYYY-MM-DD") {

	if (isEmpty(val) || isEmpty(format)) return val;
	if (typeof format !== 'string') return val;
	if (typeof val === 'string') {
		if (system.osName === 'ios') {
			val = val.replace(/-/g, '/').replace(/T/g, ' ').split('.')[0];
		} else {
			val = val.replace(/T/g, ' ').split('.')[0];
		}
	}

	try {
		let date = new Date(val);
		const fullYear = date.getFullYear(),
			month = date.getMonth() + 1,
			dateday = date.getDate(),
			hours = date.getHours(),
			minutes = date.getMinutes(),
			seconds = date.getSeconds()

		const fm = {
			YYYY: fullYear,
			yyyy: fullYear,
			YYY: fullYear,
			yyy: fullYear,
			YY: fullYear.toString().padStart(2, '0'),
			yy: fullYear.toString().padStart(2, '0'),
			Y: fullYear % 100,
			y: fullYear % 100,
			MM: month.toString().padStart(2, '0'),
			M: month,
			DD: dateday.toString().padStart(2, '0'),
			dd: dateday.toString().padStart(2, '0'),
			D: dateday,
			d: dateday,
			HH: hours.toString().padStart(2, '0'),
			hh: hours.toString().padStart(2, '0'),
			H: hours,
			h: hours,
			mm: minutes.toString().padStart(2, '0'),
			m: minutes,
			ss: seconds.toString().padStart(2, '0'),
			s: seconds
		}

		let res = format;
		for (let key in fm) {
			res = res.replace(new RegExp(key, 'g'), fm[key]);
		}

		return res;
	} catch (e) {
		console.log(e)
		return val;
	}
}

/**
 * 时间格式转换
 * @param { String } val 需要转换的值
 * @param { String } format 转换的格式，默认年月日(hh:mm:ss)
 * @returns 格式化时间字符串
 */
export function timeFormat(val = null, format = "HH:mm:ss") {
	if (isEmpty(val) || isEmpty(format)) return val;
	if (typeof format !== 'string') return val;

	try {
		let hours = 0;
		let minutes = 0;
		let seconds = 0;
		if (val.includes(':')) {
			const sp = val.split(':');
			hours = sp.length > 0 ? +sp[0] : 0;
			minutes = sp.length > 1 ? +sp[1] : 0;
			seconds = sp.length > 2 ? +sp[2] : 0;
		}

		const fm = {
			HH: hours.toString().padStart(2, '0'),
			hh: hours.toString().padStart(2, '0'),
			H: hours,
			h: hours,
			mm: minutes.toString().padStart(2, '0'),
			m: minutes,
			ss: seconds.toString().padStart(2, '0'),
			s: seconds
		}

		let res = format;
		for (let key in fm) {
			res = res.replace(new RegExp(key, 'g'), fm[key]);
		}

		return res;
	} catch (e) {
		console.log(e);
		return val;
	}
}

/**
 * 日期字符转日期对象
 * @param { String } val 需要转换的值
 * @returns 日期对象
 */
export function strToDate(val) {
	if (isEmpty(val)) return val;
	if (typeof format !== 'string') return val;

	if (typeof val === 'string') {
		if (system.osName === 'ios') {
			val = val.replace(/-/g, '/');
		} else {
			val = val.replace(/T/g, ' ');
		}
	}

	return new Date(val)
}


/****** moneyFormat 格式转换：金额“,”分段格式化 ****************************************************************************************/
/**
 * 金额分段格式化
 * @param {number} money 
 * @param {bit} bit 
 */
export function moneyFormat(money = 0, bit = 3) {
	if (isEmptys([money, bit])) return money;
	return money.toString().replace(new RegExp(`\\B(?=(\\d{${bit}})+(?!\\d))`, 'g'), ",");
}


/****** arrayToTree 格式转换：数组转树 ************************************************************************************************/
/**
 * 数组转树
 * @param {Array|String} array 需要转化的数组
 * @param {String} key 关键字字段名
 * @param {String} parentKey 父级编号字段
 * @param {String} childrenKey 孩子节点字段
 * @returns {Array} 树
 */
export function arrayToTree(array = [], key = 'id', parentKey = 'parentId', childrenKey = 'children') {
	if (isEmpty(array)) return []
	// 默认参数
	let _default = {
		data: [],
		key: "id",
		parentKey: 'parentId',
		childrenKey: 'children'
	}
	let result = []

	// 如果是字符串，先转换为对象再校验格式
	if (typeof array === 'string') {
		try {
			let _arr = JSON.parse(array);
			if (_arr instanceof Array) {
				// 反序列化后如果是数组，则继续
				_default.data = _arr;
			} else {
				// 不是数组，则格式错误
				console.log('数据格式错误', _arr);
				return _default.data;
			}
		} catch (e) {
			// 反序列化失败, 说明数据格式有误
			console.log('数据格式错误', e);
			return _default.data;
		}
	} else if (array instanceof Array) {
		// 如果是数组，直接克隆
		_default.data = JSON.parse(JSON.stringify(array));
	} else {
		// 其他数据格式，不满足要求
		console.log('数据格式错误', _arr);
		return _default.data;
	}

	if (!isEmpty(key)) _default.key = key;
	if (!isEmpty(parentKey)) _default.parentKey = parentKey;
	if (!isEmpty(childrenKey)) _default.childrenKey = childrenKey;
	if (array.length) {
		let allIdMap = {};

		array.forEach(item => {
			const _id = item[_default.key];
			if (!isEmpty(_id)) allIdMap[_id] = item;
		})

		array.forEach(item => {
			const _pid = item[_default.parentKey];

			if (!isEmpty(_pid)) {
				const parent = allIdMap[_pid];
				if (parent) {
					// 如果存在父级节点，将当前节点添加到父级节点的孩子节点集合
					if (isEmpty(parent[_default.childrenKey])) parent[_default.childrenKey] = [];
					parent[_default.childrenKey].push(item);
				} else {
					// 顶级节点，这里的item是引用对象
					result.push(item);
				}
			}
		})
	}

	return result;
}

// 参数格式化
export function formatQuery(params = {}) {
	let query = ["__v=1"]
	for (let key in params) {
		query.push(`&${key}=${params[key]}`)
	}
	return query.join("").replace('__v=1&', '')
}

export function treeJson(json, id, pid) {

	let data = JSON.parse(JSON.stringify(json));
	if (!data || !data.length) return [];
	let targetData = []; //存储数据的容器(返回)
	let records = {};
	let itemLength = data.length; //数据集合的个数
	for (let i = 0; i < itemLength; i++) {
		let o = data[i];
		records[o[id]] = o;
	}
	for (let i = 0; i < itemLength; i++) {
		let currentData = data[i];
		let parentData = records[currentData[pid]];
		if (!parentData) {
			targetData.push(currentData);
			continue;
		}
		parentData.children = parentData.children || [];
		parentData.children.push(currentData);
	}
	return targetData;
}


export function pageJson(json, currentPage, pagePercount) {

	for (var i = 0; i < json.length; i++) {
		json[i]["ShowInPage"] = Math.floor(i / pagePercount) + 1;
		json[i]["IsInPage"] = false;
		if (json[i]["ShowInPage"] == currentPage) {
			json[i]["IsInPage"] = true;
		}
	}
	return json;
}


export function distinctJson(json, key, value) {
	var temp = [];
	temp.push({
		"Key": 0,
		"Value": "未选择"
	})
	for (var i = 0; i < json.length; i++) {
		var exist_grade = false;
		for (var j = 0; j < temp.length; j++) {
			if (temp[j]["Key"] == json[i][key]) {
				exist_grade = true;
				break;
			}
		}
		if (!exist_grade) {
			temp.push({
				"Key": json[i][key],
				"Value": json[i][value]
			});
		}
	}
	return temp;
}


export function childJson(json, columnValue, columnLabel, deep) {
	var temp = [];
	var orgJson = [];
	if (deep) {
		orgJson = JSON.parse(JSON.stringify(json));
	} else {
		orgJson = json;
	}
	for (var i = 0; i < orgJson.length; i++) {
		var exist = false;
		for (var j = 0; j < temp.length; j++) {
			//console.log(temp[j]["title"] +":"+ json[i][columnName]);
			if (temp[j]["value"] == orgJson[i][columnValue]) {
				exist = true;
				//console.log(temp[j]["title"]);
				temp[j]["children"].push(orgJson[i]);
				break;
			} else {
				exist = false;
			}
		}
		if (!exist) {
			var data = {};
			if (typeof(commondColumn) != 'undefined') {
				data[commondColumn[k]] = orgJson[i][columnLabel];
			}
			temp.push({
				"value": orgJson[i][columnValue],
				"label": orgJson[i][columnLabel],
				"children": [orgJson[i]]
			})
		}
	}
	return temp;
}

export function pivotJson(json, columnName, commondColumn, deep) {
	var temp = [];
	var orgJson = [];
	if (deep) {
		orgJson = JSON.parse(JSON.stringify(json));
	} else {
		orgJson = json;
	}
	for (var i = 0; i < orgJson.length; i++) {
		var exist = false;
		for (var j = 0; j < temp.length; j++) {
			//console.log(temp[j]["title"] +":"+ json[i][columnName]);
			if (temp[j]["title"] == orgJson[i][columnName]) {
				exist = true;
				//console.log(temp[j]["title"]);
				temp[j]["items"].push(orgJson[i]);
				break;
			} else {
				exist = false;
			}
		}
		if (!exist) {
			var data = {};
			if (typeof(commondColumn) != 'undefined') {
				for (var k = 0; k < commondColumn.length; k++) {
					data[commondColumn[k]] = orgJson[i][commondColumn[k]];
				}
			}
			temp.push({
				"title": orgJson[i][columnName],
				"data": data,
				"items": [orgJson[i]]
			})
			//console.log(data);
		}
	}
	return temp;
}


export function pivotJson2(json, columnName, commondColumn, deep) {
	var temp = [];
	var orgJson = [];
	if (deep) {
		orgJson = JSON.parse(JSON.stringify(json));
	} else {
		orgJson = json;
	}
	for (var i = 0; i < orgJson.length; i++) {
		var exist = false;
		for (var j = 0; j < temp.length; j++) {
			//console.log(temp[j]["title"] +":"+ json[i][columnName]);
			if (temp[j]["title"] == orgJson[i][columnName]) {
				exist = true;
				//console.log(temp[j]["title"]);
				temp[j]["items"].push(orgJson[i]);
				break;
			} else {
				exist = false;
			}
		}
		if (!exist) {
			var data = {};
			if (typeof(commondColumn) != 'undefined') {
				for (var k = 0; k < commondColumn.length; k++) {
					data[commondColumn[k]] = orgJson[i][commondColumn[k]];
				}
			}
			temp.push({
				"title": orgJson[i][columnName],
				"data": data,
				"items": [orgJson[i]]
			})
			//console.log(data);
		}
	}
	var result = [];
	for (var i = 0; i < temp.length; i++) {
		temp[i].data.items = temp[i].items;
		temp[i].data.title = temp[i].title
		result.push(temp[i].data);
	}
	return result;
}


export function unpivotJson(json, deep) {
	var temp = [];
	var orgJson = [];
	if (deep) {
		orgJson = JSON.parse(JSON.stringify(json));
	} else {
		orgJson = json;
	}
	for (var i = 0; i < orgJson.length; i++) {
		for (var j = 0; j < orgJson[i].items.length; j++) {
			temp.push(orgJson[i].items[j]);
		}
	}
	return temp;
}

// 班级格式化
export function formatClassName(className) {
	return className.endsWith('班') ? className : className + '班';
}

// 消息提示
export const message = {
	error(msg, callback) {
		const sleep = 2000;
		uni.showToast({
			icon: "error",
			title: msg,
			duration: sleep,
			success() {
				setTimeout(() => {
					callback && callback()
				}, sleep);
			}
		})
	},
	queryBox(msg, callback) {
		uni.showModal({
			title: "提示",
			showCancel: false,
			content: msg,
			success: function(result) {
				if (result.confirm) {
					callback && callback()
				} else if (result.cancel) {
					// console.log('用户点击取消');
				}
			}
		})
	},
	success(msg, callback) {
		const sleep = 2000;
		uni.showToast({
			icon: "success",
			title: msg,
			duration: sleep,
			success() {
				setTimeout(() => {
					callback && callback()
				}, sleep)
			}
		})
	},
	info(msg, callback) {
		uni.showToast({
			title: msg,
			success() {
				callback && callback()
			}
		})
	},
	alert(msg, callback) {
		uni.showToast({
			icon: "none",
			title: msg,
			success() {
				callback && callback()
			}
		})
	},
}

// 路由跳转
export const router = {
	navTo(path) {
		if (isNull(path)) return Promise.resolve()

		if (typeof path === 'object') {
			return uni.navigateTo(path)
		}

		return uni.navigateTo({
			url: path
		})
	},
	redirectTo(path) {
		if (isNull(path)) return Promise.resolve()

		if (typeof path === 'object') {
			return uni.redirectTo(path)
		}

		return uni.redirectTo({
			url: path
		})
	}
}

// 解构请求结果
export function deconResponse(resp) {
	return resp.data.table
}

// 字符串转日期
export function caseDate(dateStr) {
	if (isString(dateStr)) {
		if (isIos()) {
			dateStr = dateStr.replace(' ', 'T');
		} else {
			dateStr = dateStr.replace('T', ' ');
		}

		return new Date(dateStr)
	}
	return new Date(dateStr)
}

//相识度判定,返回值越小相似度越高
export function levenshteinDistance(s1, s2) {
	const dp = Array(s2.length + 1).fill(null).map(() => Array(s1.length + 1).fill(null));

	for (let i = 0; i <= s1.length; i++) {
		dp[0][i] = i;
	}

	for (let j = 0; j <= s2.length; j++) {
		dp[j][0] = j;
	}

	for (let j = 1; j <= s2.length; j++) {
		for (let i = 1; i <= s1.length; i++) {
			const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
			dp[j][i] = Math.min(
				dp[j - 1][i] + 1, // 删除操作
				dp[j][i - 1] + 1, // 插入操作
				dp[j - 1][i - 1] + cost // 替换操作
			);
		}
	}

	return dp[s2.length][s1.length];
}

export function TXRoom(Url, RoomNo, Pwd) {
	console.log(Url);
	console.log(RoomNo);
	// #ifdef H5
	// 浏览器环境
	window.open(Url);
	// #endif

	// #ifdef MP-WEIXIN
	// 微信小程序环境
	const user = ktluser.getUser(false);
	var name = encodeURIComponent(user.Name);
	wx.navigateToMiniProgram({
		appId: 'wx33fd6cdc62520063', // 固定的腾讯会议微信小程序appid
		path: 'pages/index/index?code=' + RoomNo + "&nm=" + name + "&pwd=" + Pwd, // 要跳转到的页面路径
		success() {
			console.log('跳转成功')
		},
		fail(err) {
			console.log(err, '跳转失败')
		}
	});
	// #endif


}

/** 创建组件 Options */
export function createOptionsMixins(name) {
	return {
		name,
		inheritAttrs: false,
		options: {
			virtualHost: true
		}
	}
}

/**
 * 通用api
 */
export default {
	getUuid,
	dateFormat,
	moneyFormat,
	deepMerge,
	deepClone,
	arrayToTree,
	random,
	randomArray,
	toNumber,
	treeJson,
	pageJson,
	distinctJson,
	childJson,
	pivotJson,
	pivotJson2,
	unpivotJson,
	formatQuery,
	formatClassName,
	message,
	router,
	deconResponse,
	caseDate,
	levenshteinDistance,
	getVersion,
	TXRoom
}